package core.controller;

import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.EurekaClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;
import java.util.Objects;
import java.util.Random;

@RestController
public class MainController {
    public static final String SERVICE_ID_PROVIDER = "provider";
    //spring抽象的接口，参考Eureka，定义了标准，谁实现谁加入，consul，nacos都实现了，功能简单
    @Autowired
    DiscoveryClient client;

    @GetMapping("/getServices")
    public Object getServices() {
        return client.getServices();
    }

    @GetMapping("/getInstances")
    public Object getInstances() {
        return client.getInstances(SERVICE_ID_PROVIDER);
    }

    @Autowired
    EurekaClient eurekaClient;

    @GetMapping("/getFirstInstances")
    public Object getFirstInstances() {
        //使用服务名找列表
        List<InstanceInfo> providers = eurekaClient.getInstancesByVipAddress(SERVICE_ID_PROVIDER, false);
        if (Objects.isNull(providers) || providers.isEmpty()) {
            return "no provider";
        }

        InstanceInfo first = providers.getFirst();
        if (!InstanceInfo.InstanceStatus.UP.equals(first.getStatus())) {
            return "no up instance";
        }
        String url = "http://" + first.getHostName() + ":" + first.getPort() + "/getHi";
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate.getForObject(url, String.class);
    }

    //Spring慢慢接口化，org.springframework.cloud.client.loadbalancer.LoadBalancerClient，Ribbon也是其中一种实现
    @Autowired
    LoadBalancerClient lb;
    @Qualifier("loadBalanced")
    @Autowired
    RestTemplate restTemplate;

    @GetMapping("/loadBalance")
    public Object loadBalance() {
        //使用服务,返回非down的服务列表
        ServiceInstance provider = lb.choose(SERVICE_ID_PROVIDER);
        if (Objects.isNull(provider)) {
            return "no provider";
        }
        String url = "http://" + provider.getServiceId() + ":" + provider.getPort() + "/getHi";
        RestTemplate restTemplate = new RestTemplate();
        String result = restTemplate.getForObject(url, String.class);
        String s = provider.getPort()+"返回内容：" + result;
        System.out.println(s);
        return s;
    }

    @Autowired
    DiscoveryClient discoveryClient;
    @GetMapping("/random")
    public Object random(){
        List<ServiceInstance> instances = discoveryClient.getInstances(SERVICE_ID_PROVIDER);
        int nextInt = new Random().nextInt(instances.size());
        ServiceInstance instance = instances.get(nextInt);
        String url = "http://" + instance.getHost() + ":" + instance.getPort() + "/getHi";
        RestTemplate restTemplate = new RestTemplate();
        String result = restTemplate.getForObject(url, String.class);
        String s = instance.getPort()+"返回内容：" + result;
        System.out.println(s);
        return s;
    }
    /**
     * 结合
     *     @Bean
     *     @LoadBalanced
     *     RestTemplate loadBalanced() {
     *         return new RestTemplate();
     *     }
     * 使用，注入的restTemplate会有问题，consumer这边请求地址和返回的端口号输出不一致，provider返回没有问题，怀疑高版本导致
     */
    @GetMapping("/round")
    public Object round() {
        //使用服务,返回非down的服务列表
        ServiceInstance provider = lb.choose(SERVICE_ID_PROVIDER);
        if (Objects.isNull(provider)) {
            return "no provider";
        }
        String url = "http://" + provider.getHost() + ":" + provider.getPort() + "/getHi";
        RestTemplate restTemplate = new RestTemplate();
        String result = restTemplate.getForObject(url, String.class);
        String s = provider.getPort()+"返回内容：" + result;
        System.out.println(s);
        return s;
    }

    /**
     * 结合
     *     @Bean
     *     @LoadBalanced
     *     RestTemplate loadBalanced() {
     *         return new RestTemplate();
     *     }
     * 使用，restTemplate完成url的拼接，不手动拼接host:port
     */
    @GetMapping("/rest")
    public Object rest() {
        String url = "http://" + SERVICE_ID_PROVIDER + "/getHi";
        /**
         * getForObject返回出参，也就是接口的返回值信息
         * getForEntity返回信息更多，诸如请求头信息
         */
        String result = restTemplate.getForObject(url, String.class);
        String s = "返回内容：" + result;
        System.out.println(s);
        return s;
    }
}
